/**
 * @Title: FileDownLoader.java
 * @Package com.hxd.love.util
 * @Description: TODO(用一句话描述该文件做什么)
 * @author 谢会超
 * @date 2015-10-22 下午8:45:19
 * @version V1.0
 */

package net.bblot.lottery.util;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import net.bblot.lottery.api.http.HttpConnect;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName: FileDownLoader
 * @Description: TODO(文件下载器)
 * @author 谢会超
 * @date 2015-10-22 下午8:45:19
 *
 */

public class FileDownLoader {
    public final static String TAG = "FileDownLoader";
    private static Object lock = FileDownLoader.class;

    /** 下载状态 */
    public static final int Not_exist = 1;
    public static final int Exsist = 2;
    public static final int Downloading = 3;

    private static final int RESULT_CODE_OK = 1;
    private static final int RESULT_CODE_FAILUR = -1;
    private static final int MSG_DOWNLOAD_PERCENT = 1001;

    private static FileDownLoader instance;
    private ExecutorService exu;

    private Handler handler;
    private ArrayList<DownLoadListener> dl_array;

    public HashMap<String, Integer> map;

    public static FileDownLoader getInstance() {
        synchronized (lock) {
            if (instance == null) {
                instance = new FileDownLoader();

            }
            return instance;
        }
    }

    private FileDownLoader() {
        exu = Executors.newFixedThreadPool(3);
        map = new HashMap<String, Integer>();
        dl_array = new ArrayList<DownLoadListener>();
        handler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                String filePath = (String) msg.obj;
                int percent = msg.arg1;
                switch (msg.what) {
                    case RESULT_CODE_OK:
                        map.remove(filePath);
                        for (DownLoadListener dl : dl_array) {
                            dl.onFileDownLoadResult(filePath, true);
                        }
                        for (DownLoadListener dl : dl_array) {
                            removeDownLoadListener(dl);
                        }
                        break;
                    case RESULT_CODE_FAILUR:
                        map.remove(filePath);
                        for (DownLoadListener dl : dl_array) {
                            dl.onFileDownLoadResult(filePath, false);
                        }
                        for (DownLoadListener dl : dl_array) {
                            removeDownLoadListener(dl);
                        }
                        break;
                    case MSG_DOWNLOAD_PERCENT:
                        for (DownLoadListener dl : dl_array) {
                            dl.onPercentUpdate(percent);
                        }
                        break;
                }

            }

        };
    }

    public int getFileStatus(final String fileName, final String parentPath) {

        if (map.containsKey(parentPath + fileName + "")) {
            return Downloading;
        } else {
            File newfile = new File(parentPath + fileName);
            if (newfile.exists()) {
                return Exsist;
            } else {
                return Not_exist;
            }
        }

    }

    public void addDownLoadListener(DownLoadListener dl) {
        if (dl != null) {
            dl_array.add(dl);
        }
    }

    public void removeDownLoadListener(DownLoadListener dl) {
        if (dl != null) {
            dl_array.remove(dl);
        }
    }

    public void finish() {
        instance = null;
    }

    /**
     *
     * @param context
     * @param url
     * @param fileName 请确保parentPath+fileName是一个合法路径
     * @param parentPath
     */
    public void downLoad(final Context context, final String url,
                         final String fileName, final String parentPath) {


        map.put(parentPath + fileName + "", Downloading);
        Runnable run = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                boolean rename_ok = false;
                try {

                    HttpConnect.PercentListener listener = new HttpConnect.PercentListener() {
                        @Override
                        public void onPercentUpdate(int per) {
                            final Message message = handler.obtainMessage(MSG_DOWNLOAD_PERCENT);
                            message.arg1 = per;
                            handler.sendMessage(message);
                        }
                    };
                    boolean down_ok = HttpConnect.donwLoadFile(context,
                            fileName + "_tmp", url, parentPath, listener);
                    if (down_ok) {
                        File file = new File(parentPath, fileName + "_tmp");
                        File newfile = new File(parentPath, fileName);
                        if (newfile.exists()) {
//							Log.d(TAG, "76" + newfile.exists());
                            boolean delete_ok = newfile.delete();
//							Log.d(TAG, "79delete_ok" + delete_ok);
                        }
                        rename_ok = file.renameTo(newfile);
//						Log.d(TAG, "153renameTo" +rename_ok+ file.getAbsolutePath());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Message msg = new Message();
                msg.obj = parentPath + File.separator + fileName;
                if (rename_ok) {
                    msg.what = RESULT_CODE_OK;
                } else {
                    msg.what = RESULT_CODE_FAILUR;
                }
                handler.sendMessage(msg);
            }
        };
        exu.execute(run);
    }

    public interface DownLoadListener {
        void onFileDownLoadResult(String filePath, boolean down_ok);
        void onPercentUpdate(int per);
    }

}
